<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="js/vue.js"></script>
</head>
<body>
<div id="app">
    <input-number v-model="value" :max="1000" :min="0" :step="11"></input-number>
</div>
<script>
    function isValueNumber(value){
        return (/(^[\-0-9][0-9]*(.[0-9]+)?)$/)
    }
    Vue.component('input-number',{
        template:`
        <div class="input-number">
             <input type="text" :value="currentValue" @change="handleChange" @keyup.up="handleUp" @keyup.down="handleDown">
             <button @click="handleDown" :disabled="currentValue<=min">-</button>
             <button @click="handleUp" :disabled="currentValue>=max">+</button>
        </div>
        `,
        props:{
            max:{
                type:Number,
                default: Infinity
            },
            min:{
                type:Number,
                default:-Infinity
            },
            value:{
                type:Number,
                default:0
            },
            step:{
                type:Number,
                default:0
            }
        },
        data(){
            return{
                currentValue: this.value
            }
        },
        watch:{
            currentValue(val){
                this.$emit('input',val)
                this.$emit('on-change',val)
            },
            value(val){
                this.updateValue(val)
            }
        },
        methods:{
            updateValue(val) {
                if (val>this.max) val=this.max
                if (val<this.min) val=this.min
                this.currentValue=val
            },
            handleDown(){
                if (this.currentValue<=this.min) return false
                this.currentValue -= this.step
            },
            handleUp(){
                if (this.currentValue>=this.max) return false
                this.currentValue += this.step
            },
            handleChange(event){
                var val = event.target.value.trim()
                var max = this.max
                var min = this.min
                if (isValueNumber(val)){
                    val=Number(val)
                    this.currentValue=min
                    if (val>max){
                        this.currentValue=max
                    } else if (val<min) {
                        this.currentValue=min
                    }
                }else {
                    event.target.value=this.currentValue
                }
            }
        },
        mounted(){
            this.updateValue(this.value)
        }
    })
    var vm = new Vue({
        el:'#app',
        data:{
            value: 0
        },
        methods:{}
    })
</script>
</body>
</html>
